package server

import (
	v1 "chat/app/api/v1"
	"chat/app/routes"
	"chat/middleware"
	"chat/setting"
	"chat/utils"
	"chat/utils/logger"
	"github.com/fvbock/endless"
	"github.com/gin-gonic/gin"
	"io"
	"log"
	"net/http"
	"os"
	"time"
	//_ "chat/setting/toml"
	//_ "chat/setting/etcd"
)

type HttpTest struct {
}

func NewHttpTest() *HttpTest {
	return &HttpTest{}
}

// GinNewTest 初始化gin
func (s *HttpTest) GinNewTest() *gin.Engine {
	// 启动模式
	gin.SetMode(setting.Server.RunMode)

	if "debug" == setting.Server.RunMode {
		// 日志始终着色
		gin.ForceConsoleColor()
		// 将日志写入文件
		f, _ := os.Create(setting.Server.LogPath + "/see.log")
		gin.DefaultWriter = io.MultiWriter(f, os.Stdout)      // 日志信息
		gin.DefaultErrorWriter = io.MultiWriter(f, os.Stdout) // 错误信息
	}

	// 没有中间件的引擎
	router := gin.New()
	if "debug" == setting.Server.RunMode {
		router.Use(gin.Logger())
	}
	router.Use(gin.Recovery())

	// Content Keys 需要放在路由前面进行初始化
	router.Use(middleware.ContentKeys())
	// 定义全局的CORS中间件
	router.Use(middleware.Cors())

	// 自定义Logger
	router.Use(middleware.Logger())
	go logger.LogHandlerFunc() // 异步处理日志

	// 导入所有模板
	//routes.LoadHTML(router, getStaticSUB(s.websiteFiles, "website/tpl"))
	// embed 方式加载静态资源 (embed 打包成二进制文件)
	//router.StaticFS("/asset", http.FS(getStaticSUB(s.websiteFiles, "website/asset")))
	//router.StaticFileFS("/favicon.ico", "favicon.ico", http.FS(s.resourcesFiles))
	//router.StaticFS("/public", http.FS(getStaticFS(s.websiteFiles, "website/static")))

	// 上传的文件需要访问独立的文件夹
	router.StaticFS("/public", http.Dir("./website/static"))
	router.StaticFS("/asset", http.Dir("./website/asset"))       // 这个是直接访问文件夹路径的方式 访问静态资源
	router.StaticFile("/favicon.ico", "./resources/favicon.ico") // ico 站点图标

	// 限流 tollbooth-limit 中间件
	//router.Use(middleware.LimitHandler())
	// 限流 rate-limit 中间件
	router.Use(middleware.NewRateLimiter())

	// 注册静态路由
	routes.Routes(router)

	// 注册动态路由 以api开头
	routes.NewAny(router)

	// redis 初始化
	utils.InitRedis()
	// gorm 初始化
	utils.InitDB()
	// es 初始化
	//utils.InitES()
	// 开启etcd 并 监听降级服务开关
	go utils.NewEtcd().ListenReduceRank()

	// chat 发送消息
	go v1.SendMessage()

	return router
}

// HttpServerTest 启动服务 & 优雅Shutdown（或重启）服务
func (s *HttpTest) HttpServerTest(router *gin.Engine) {
	// endless 热启动
	els := endless.NewServer(":"+setting.Server.Port, router)
	els.ReadHeaderTimeout = time.Duration(setting.Server.ReadTimeout) * time.Second
	els.WriteTimeout = time.Duration(setting.Server.WriteTimeout) * time.Second

	err := els.ListenAndServe()
	if err != nil {
		log.Println(err)
	}
	log.Println("Server on " + setting.Server.Port + " stopped")
}
